﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using BusinessRule.Common;
using BusinessRule.Business;
using BusinessRule.DTO;
using DatabaseAccess.DBUtility;
using System.Threading.Tasks;
using System.Configuration;
using System.Collections;

//Description:预排产定时任务处理类
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:zhangrj
//create Date:2025-01-14
//Rewriter:
//Rewrite Date:
namespace MESScheduledTask
{
    public class TryApsScheduledTask
    {
        public static readonly int maxParallelSync = Convert.ToInt32(ConfigurationManager.AppSettings["maxParallelSync"].ToString());//最大并行任务数
        private TryLimitedCapacityBusiness m_LMObj = new TryLimitedCapacityBusiness();
        /// <summary>
        /// 执行任务
        /// </summary>
        /// <param name="taskList"></param>
        public void RunTaskSync(List<string> taskList)
        {
            //获取需要启动的任务
            DataTable dt = CommonHelper.GetNeedExecuteTask(CommonHelper.TaskTypeEnum.自动预排产);
            List<Task> tl = new List<Task>();

            foreach (DataRow dr2 in dt.Rows)
            {//开始循环定时任务
                var tempDt = dt.Clone();
                tempDt.ImportRow(dr2);
                var dr = tempDt.Rows[0];//此处必须要给局部变量赋值

                if (taskList.Count >= maxParallelSync)
                {
                    LogHelp.WriteLog("当前正在执行的任务数为：" + taskList.Count.ToString() + " 已达到最大并行限制----------------------------------------------------------------------");
                    break;
                }
                if (taskList.Contains(dr["scheduledtaskid"].ToString()))//已在任务中
                    continue;

                taskList.Add(dr["scheduledtaskid"].ToString());//添加到list中

                tl.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        DealAutoTryApsTask(dr);
                    }
                    catch (Exception ex)
                    {
                        LogHelp.WriteError(dr["taskname"].ToString() + "定时计算异常", ex);
                        CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "3", ex.Message + ex.StackTrace, "1");
                        return;
                    }
                    finally
                    {
                        LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕，移除队列");
                        taskList.Remove(dr["scheduledtaskid"].ToString());
                    }
                }, TaskCreationOptions.LongRunning));

            }
            //本次产生的task，需要等待完毕
            Task.WaitAll(tl.ToArray());
        }

        /// <summary>
        /// 处理单个任务
        /// </summary>
        /// <param name="dr"></param>
        public void DealAutoTryApsTask(DataRow dr)
        {
            if (dr["type"].ToString() == "自动未执行")
            {
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "2", "", "1");//开始执行
                LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 开始执行----------------------------------------------------------------------");
            }
            Dictionary<string, string> dicAttr = CommonHelper.GetTaskAttr(dr["ScheduledTaskId"].ToString());//获取定时任务的属性
           
            //开始启动这次任务
            var sqlList = new ArrayList();
            DataTable containerDt = m_LMObj.GetApsPoolContainerInfo(new Dictionary<string, string>() { { "PoolID", dicAttr["排产池"] }, { "IsTryAps", "1" } }).DBTable;
            if (containerDt.Rows.Count == 0)
            {
                goto end;
            }

            CommonHelper.UpdateTaskLogStartDate(dr["ScheduledTaskId"].ToString());//更新定时任务日志的开始时间为当前时间 add by zhangrj 20240328

            DataTable ApsLmCalculateDt = containerDt.DefaultView.ToTable(true, "apspoolid", "ISSUBCON", "containerid", "containername", "workflowid", "ENDTIME",
                "CONTAINERTYPE", "TOGETHERFLAG", "BEGINSEQUENCE", "EXPECTMATERIALDATE", "REALSTARTDATE");
            ApsLmCalculateDt.Columns.AddRange(new DataColumn[] { new DataColumn("STARTTIME"), new DataColumn("DJDKSPECIAL") });
            DataTable ApsLmCalculateDt2 = ApsLmCalculateDt.AsEnumerable().Select((DataRow row) =>
            {
                row["STARTTIME"] = string.IsNullOrWhiteSpace(row["EXPECTMATERIALDATE"].ToString()) ? row["REALSTARTDATE"] : row["EXPECTMATERIALDATE"];
                row["DJDKSPECIAL"] = 2;
                return row;
            }).CopyToDataTable();
            DataTable faConDt = ApsLmCalculateDt2.Select("ISSUBCON is null").CopyToDataTable();//主卡    
            if (ApsLmCalculateDt2.Select("ISSUBCON='1'").Length > 0)//子卡
            {
                faConDt.Merge(ApsLmCalculateDt2.Select("ISSUBCON='1'").CopyToDataTable());
            }
            //开始排产计算
            Dictionary<string, string> para = new Dictionary<string, string>();
            para["EmployeeID"] = "";//排产人暂时置空

            int num = 0;
            foreach (DataRow conRow in faConDt.Rows)
            {
                num++;
                //检查是否提前终止
                if (DatabaseHelper.GetSingle(string.Format(@"select 1 from ScheduledTaskLogs sl
                            where sl.scheduledtaskid='{0}' and sl.islatest=1 and sl.taskexeendtime is not null", dr["ScheduledTaskId"].ToString())) != null)
                {
                    LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕----------------------------------------------------------------------");
                    return;
                }
                try
                {
                    var apsConDt = conRow.Table.Clone();
                    apsConDt.ImportRow(conRow);
                    var result = m_LMObj.LMPositiveCalculate(apsConDt, para);
                    LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 的批次：第：" + num.ToString() + "个 " + conRow["containername"].ToString() + " 排产计算完毕 " + result.Message);                
                }
                catch (Exception ex)
                {
                    LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 的批次：第：" + num.ToString() + "个 " + conRow["containername"].ToString() + " 排产计算错误 " + ex.Message);
                }

            }
        end:
            //此任务执行完毕
            CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，批次数：" + containerDt.Rows.Count.ToString(), "1");
            LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕----------------------------------------------------------------------");
        }
    }
}
